import re
import logging
import urllib
import argparse
import sys
import urllib.request as req


def check_port(host, protocol, port):
	assert protocol == 'TCP' or protocol == 'UDP', "Protocol must be UDP or TCP, not %s" % protocol
	assert int(port) < 65535 and int(port) > 0, "Port must be in range 1-6555, not %s" % port
	
	try:
		m = base64online(host, protocol, port)
	except:
		logging.debug('base64online failed')
	else:
		return m
	logging.debug('trying another service')
	logging.debug('no other services. exiting..')
	return 'fail'
	
def base64online(host, prot, port):

	proxy = req.ProxyHandler({'http':r'http://db2:practicePR0XY@192.168.30.16:3128'})
	auth = req.HTTPBasicAuthHandler()
	opener = req.build_opener(proxy, auth, req.HTTPHandler)
	req.install_opener(opener)
	url = "http://www.base64online.com/port-check.php?ho=" + host + "&pr=" + prot + "&prt=" + port
	conn = req.urlopen(url)
	logging.debug('%s opened', url)
	
	if conn.getcode() != 200:
		raise urllib.error.URLError('Status is not 200')
		
	return_str = conn.read().decode("utf-8")
	re_string = 'Checking ' + prot + '.<br>Port ' + port + ' is <font color=\"[a-z]{3,5}\">(closed|open)</font> at ' + host + '..'
	logging.debug('regex string %s', re_string)
	
	p =  re.compile(re_string)
	#web: Checking TCP.<br>Port 1 is <font color="red">closed</font> at 8.8.8.8
	#result = closed
	m = p.search(return_str).group(1)
	logging.debug('result is %s', m)

	return m
	
	
if __name__ == "__main__":
	parser = argparse.ArgumentParser()
	parser.add_argument('host', help="Hostname or IP")
	parser.add_argument('proto', help="Protocol: UDP or TCP")
	parser.add_argument('port', help="Port in range 1-65535")
	parser.add_argument('--debug', action='store_true', help='Set to additional output')
	args = parser.parse_args()
	if args.debug == True:
		logging.basicConfig(format = u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s]  %(message)s', level = logging.DEBUG)
		
	m = check_port(args.host, args.proto, args.port)
	if m == 'open':
		print('{0} port {1} is open at {2}'.format(args.proto, args.port, args.host))
		sys.exit(0)
	elif m == 'closed':
		print('{0} port {1} is closed at {2}'.format(args.proto, args.port, args.host))
		sys.exit(0)
	elif m == 'fail':
		print('Request failed, try --debug')
		sys.exit(1)
	else:
		print('Unidentified response. try --debug')
		sys.exit(1)
	